import * as THREE from 'three'

/** 屏幕坐标转wengl坐标 */
export function screenToWebgl(event) {
  const { clientX, clientY, path } = event
  const element = path[0]
  // left, top 表示canvas画布相对body左右偏移量:像素
  // width,height 表示canvas画布的宽高
  const { left, top, width, height } = element.getBoundingClientRect();

  //屏幕坐标转标准设备坐标
  // 减去canvas画布的偏移量left  top
  return [((clientX - left) / width) * 2 - 1, -((clientY - top) / height) * 2 + 1]
}
/** 屏幕坐标转three坐标 */
export function screenToThree(event, editor) {
  let { camera } = editor
  let [x, y] = screenToWebgl(event)
  // 设备坐标转three世界坐标
  let v3 = new THREE.Vector3(x, y, 0).unproject(camera)
  return [v3.x, v3.y]
}

/** 屏幕移动距离转three距离 */
export function moveToThree(delta, editor) {
  let { renderer, camera } = editor
  const { width, height } = renderer.domElement.getBoundingClientRect();
  // 相机近裁剪面尺寸
  const cameraW = camera.right - camera.left
  const cameraH = camera.top - camera.bottom
  // 指针移动距离在画布中的比值
  const rotateX = delta.x / width
  const rotateY = delta.y / height
  // 把画布上的移动距离转换成相机裁剪空间中的位移量
  const distanceLeft = rotateX * cameraW
  const distanceUp = rotateY * cameraH

  // 相机本地坐标系里的x轴
  const mx = new THREE.Vector3().setFromMatrixColumn(camera.matrix, 0)
  // 相机x轴平移量
  const vx = mx.clone().multiplyScalar(-distanceLeft)
  // 相机y轴平移量
  const vy = new THREE.Vector3()
  vy.setFromMatrixColumn(camera.matrix, 1)

  vy.multiplyScalar(distanceUp)
  let panOffest = new THREE.Vector3().copy(vx.add(vy))
  return panOffest.divideScalar(camera.zoom)
}

//创建一个射线投射器`Raycaster`
let raycaster = new THREE.Raycaster();
export function getSelectMesh(event, editor) {
  let [x, y] = screenToWebgl(event)
  //通过鼠标单击位置标准设备坐标和相机参数计算射线投射器`Raycaster`的射线属性.ray
  raycaster.setFromCamera(new THREE.Vector2(x, y), editor.camera);
  // 未选中对象返回空数组[],选中一个数组1个元素，选中两个数组两个元素
  let intersects = raycaster.intersectObjects(editor.roadGroup.children, true);
  // intersects.length大于0说明，说明选中了模型
  let mesh = [];
  intersects = intersects.filter(v => v.object.name !== 'Land')
  console.log("射线器返回的对象", intersects);
  if (intersects.length > 0) {
    mesh = intersects.map(v => v.object)
  }
  return mesh
}
